<template>
    <div>
        <Category :disabled="!isShowList" />
        <el-card shadow="always" :style="{ marginTop: '30px' }" :body-style="{ padding: '20px' }">
            <template #header v-if="isShowList">
                <el-button :disabled="!category3Id" type="primary" size="default" @click="addAttr" :icon="Plus">添加</el-button>
            </template>
            <el-table v-if="isShowList" :data="attrList" border stripe>
                <el-table-column label="序号" type="index" width="100" />
                <el-table-column label="属性名称" width="200" prop="attrName"></el-table-column>
                <!-- 
                row是这一行的整个数据
             -->
                <el-table-column label="属性名称列表" prop="attrValueList">
                    <template v-slot="{ row }">
                        <el-tag v-for="item in row.attrValueList" :key="item.id" class="ml-2" type="success">
                            {{ item.valueName }}</el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="200">
                    <template v-slot="{ row }">
                        <el-button @click="editAttr(row)" :icon="Edit" type="success">修改</el-button>
                        <el-popconfirm
                                    title="你确定要删除吗"
                                    @confirm="deleteAttr(row.id)">
                                    <template #reference>
                                        <el-button :icon="DeleteFilled" @click="" type="danger">删除</el-button>
                                    </template>
                                </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            <div v-else>
                <el-form :inline="true">
                    <el-form-item label="属性名">
                        <el-input v-model="newAttrData.attrName" placeholder="输入属性名"></el-input>
                    </el-form-item>
                    <div>
                        <el-form-item>
                            <el-button :disabled="!newAttrData.attrName" @click="addAttrValue" type="primary">立即创建</el-button>
                            <el-button @click="cancle">取消</el-button>
                        </el-form-item>
                    </div>

                </el-form>
                <div>
                    <el-table :data="newAttrData.attrValueList" :style="{ marginBottom: '20px' }" border stripe>
                        <el-table-column type="index" label="序号" width="50px" />
                        <el-table-column prop="valueName" label="属性值名称">
                            <template v-slot="{ row, $index }">
                                <el-input ref="editEle" @focus="saveOldValue(row)" @blur="changeToLook(row, $index)"
                                    v-if="row.isEdit" v-model="row.valueName" placeholder="输入属性值名称"></el-input>
                                <span :style="{ display: 'inline-block', width: '70%' }" @click="changeToEdit(row)"
                                    v-else>{{
                                            row.valueName
                                    }}</span>
                            </template>
                        </el-table-column>
                        <el-table-column label="操作">
                            <template v-slot="{$index}">
                                <el-popconfirm
                                    title="你确定要删除吗"
                                    @confirm="deleteAttrValue($index)">
                                    <template #reference>
                                        <el-button type="danger" size="default"  :icon="DeleteFilled" @click=""></el-button>
                                    </template>
                                </el-popconfirm>                   
                            </template>
                        </el-table-column>
                    </el-table>
                    <el-button :disabled="!newAttrData.attrName||newAttrData.attrValueList.length<=0" @click="saveAttr" type="primary">保存</el-button>
                    <el-button @click="cancle" type="default">取消</el-button>
                </div>
            </div>
        </el-card>
    </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { ElMessage } from 'element-plus';

export default defineComponent({
    name: "Attr",
});
</script>

<script setup lang="ts">
import { watch, ref, nextTick } from 'vue'
import { Plus, DeleteFilled, Edit } from "@element-plus/icons-vue";
import useAttrStore from "@/stores/attr";
import { storeToRefs } from "pinia";
import { requestAttrList, requestDeletAttr, requestUpdateOrAddAttr, type attrListItemType } from '@/api/attr'
import type { attrListType, attrValueListType } from '@/api/attr'
import cloneDeep from 'lodash/cloneDeep';


const attrStore = useAttrStore()
const { category1Id, category2Id, category3Id } = storeToRefs(attrStore)
//1.获取属性列表的逻辑
//存放三级分类得到的属性列表
const attrList = ref<attrListType>([])

//封装一个获取属性列表的请求函数
const getAttrList = async () => {
    try {
        console.log(111);
        const re = await requestAttrList(category1Id.value as number, category2Id.value as number, category3Id.value as number)
        attrList.value = re
    } catch (e: any) {
        ElMessage.error(e)
    }
}
//监听第三级分类的改变,然后请求属性列表
watch(
    category3Id,
    async (newVal) => {
        if (!newVal) return

        getAttrList()
    },
    // 立即监听 一进来页面就发送函数
    { immediate: true }
)


//2.添加平台逻辑
//数据保存平台属性页是否展示,可以切换到新增或者修改页
const isShowList = ref(true)

//定义一个新增平台属性的一个初始数据,将来点击保存的时候,把这个值提交
const newAttrData = ref<attrListItemType>({
    attrName: '',
    categoryId: category3Id.value as number,
    categoryLevel: 3,
    attrValueList: []
})

//新增平台属性事件函数
const addAttr = () => {
    //先切换到新增页
    isShowList.value = false

    //每次新增的时候,清空上一次可能残留的数据(重新给newAttrData赋一个初始值)
    newAttrData.value = {
        attrName: '',
        categoryId: category3Id.value as number,
        categoryLevel: 3,
        attrValueList: []
    }
}


//取消新增或者修改的功能的视图
const cancle = () => {
    isShowList.value = true
}

//给新增的属性,添加属性值的事件回调函数
const addAttrValue = () => {
    //先创建一个属性值的数据
    const newAttrValue = ref({
        valueName: '',//当前新增属性值的内容(目前为空占位,等视图渲染之后,在input中数据双向绑定输入)
        attrId: newAttrData.value.id,//当前属性值所在的属性的id(就算是新增,属性没有id,也要关联,将来后端添加id的时候,就有值了)
        isEdit: true,//我们给新增的属性值数据中添加一个逻辑 isEdit代表当前模式是否是编辑模式(新增的数据肯定是编辑模式)
    })
    //把新增的属性值数据 添加到新属性的 属性值列表的数组中
    newAttrData.value.attrValueList.push(newAttrValue.value)

    nextTick(() => {
        editEle.value.focus()
    })
}

//在属性列表中修改某个属性的事件方法
const editAttr = (row: attrListItemType) => {
    //先切换新增或者修改页面
    isShowList.value = false
    //在回填数据的时候,我们遍历row中的所有值,给每一个属性值对象添加剂啊一个isEdit值为false(因为回填的数据默认是查看模式)
    const cloneRow = cloneDeep(row)
    cloneRow.attrValueList.forEach(i => {
        i.isEdit = false
    })

    //回填数据,因为视图和初始新增数据的newAttrData进行深度绑定,所以回填的时候,直接把被修改的数据赋值给newAttrData即可
    newAttrData.value = cloneRow
}

//创建一个数据用来保存编辑模式的input元素
const editEle = ref()
//切换查看模式到编辑模式 给span绑定的点击事件回调函数
const changeToEdit = (row: attrValueListType) => {
    //row是当前属性值所在的数据,把当前的数据中的isEdit变为true
    row.isEdit = true
    //让当前表单自动获取焦点(操作真实DOM的时候,看情况要放在nextTic中,等DOM加载完成才能执行)
    nextTick(() => {
        editEle.value.focus()
    })
}

let oldAttrValueName = ''
//给编辑模式绑定获取焦点事件,保存旧值
const saveOldValue = (row: attrValueListType) => {
    //先把旧值保存起来
    oldAttrValueName = row.valueName
    console.log(oldAttrValueName);

}

//接环到查看模式的事件回调函数
const changeToLook = (row: attrValueListType, $index: number) => {
    //row是当前属性值所在的数据,把当前的数据中的isEdit变为false
    row.isEdit = false

    //判断输入的是否为空
    if (!row.valueName.trim()) {
        //如果输入为空,并且旧值也为空,那么说明当前是新增属性值,并且用户没有填,直接删除
        if (!oldAttrValueName) {
            newAttrData.value.attrValueList.splice($index, 1)
        } else {
            //如果有旧值,则直接把旧值还给用户,并且把旧值清空
            row.valueName = oldAttrValueName
        }
    }

    //判断用户输入的是否有重复选项,如果有,则恢复
    let isRepeact = newAttrData.value.attrValueList.some(
        i => {
            //如果自己比较自己的时候就跳过(不跳过的话,isRepeat永远为true)
            if (i === row) { return }

            return i.valueName === row.valueName
        }
    )
    //判断在数据列表中除了row自身以外,还有没有谁的valueName值和row的值相等,如果有,则恢复旧值
    if (isRepeact) {
        if (oldAttrValueName) {
            row.valueName = oldAttrValueName
        }
        else {
            newAttrData.value.attrValueList.splice($index, 1)
        }
    }

    //统一在失去焦点事件结束的时候 清空旧值
    oldAttrValueName = ''
}

//确保删除某条属性值的回调函数
const deleteAttrValue = ($index:number)=>{
    newAttrData.value.attrValueList.splice($index, 1)
}

//确认修改或者新增的属性值列表
const saveAttr = async()=>{
    //newAttrData就是我们要发送请求的参数
    //1.在保存值的时候把isEdit属性删除掉
    newAttrData.value.attrValueList.forEach(i=>{
        delete i.isEdit
    })

    //2.判断当前的属性值列表是否为空,如果为空就不提交了
    if(newAttrData.value.attrValueList.length<=0){
        ElMessage.error('属性列表不能为空')
        return 
    }

    //发送请求
    try {
        await requestUpdateOrAddAttr(newAttrData.value)

        ElMessage.success('新增或者修改成功')
        //返回属性列表视图
        isShowList.value=true
        //重新发送请求
        getAttrList()
    } catch (e) {
        ElMessage.error('新增或者修改失败')
    }
}

//删除某条属性的回调函数
const deleteAttr = async(id:number)=>{
    //发送请求
    try {
        await requestDeletAttr(id)
        ElMessage.success('删除属性成功')
        //重新发送请求
        getAttrList()
    } catch (e) {
        ElMessage.error('删除属性失败')
    }
}
</script>